import { computed, ref } from "vue";
import {
  RouteLocation,
  RouteLocationRaw,
  useRoute,
  useRouter,
} from "vue-router";
import { isFunction, isNumber, merge } from "lodash-es";
import { defineStore } from "pinia";

import { TMenu } from "@/router/menu";

import { ALIVE_STORAGE } from "@/assets/constant";
import { useLocalStorage } from "@vueuse/core";

type TTabItem = TMenu & {
  fullPath: string;
};

export function transRouteToMenu(route: RouteLocation): TTabItem {
  const { name, path, fullPath, meta } = route;
  return merge({ type: "name" }, { name, path, fullPath, ...meta }) as TTabItem;
}

export let appNavTabsId: string | number = "";

const useAppTabsStore = defineStore("appTabs", () => {
  // console.log("options", options);

  const tabsList = useLocalStorage<any[]>(
    ALIVE_STORAGE + "__" + appNavTabsId,
    []
  );

  const aliveIncludes = computed(() =>
    tabsList.value.filter((e) => e.keepAlive).map((e) => e.path)
  );

  const targetIndex = ref();

  const acticeIndex = computed(() => {
    const { value: list } = tabsList;
    const targetPath = route.path;
    return list.findIndex((e) => e.path == targetPath);
  });

  const route = useRoute();
  const router = useRouter();

  // 其他事项处理
  // 当次会话下，定义的根路径重定向目标路径
  let rediectPath: string | RouteLocationRaw | undefined = "";
  const findRootRoute = (to: RouteLocation) => {
    if (!rediectPath) {
      const target = router.getRoutes().find((e) => e.path == "/");
      const redirect = target?.redirect;
      rediectPath = isFunction(redirect) ? redirect(to) : redirect;
    }
  };

  // 切换tab
  const changeTab = (i: number) => {
    targetIndex.value = i;
    const { fullPath } = tabsList.value[i];
    router.push(fullPath);
  };

  // 追加Tab
  const appendTab = (
    to: RouteLocation,
    from: RouteLocation,
    fn: () => boolean
  ) => {
    if (to.meta.disableTab || (fn && !fn())) return;

    findRootRoute(to);

    const list = tabsList.value;
    const tabData = transRouteToMenu(to);

    // console.log("-----appendTab", list, tabData);

    // const index = isNumber(targetIndex.value)
    //   ? targetIndex.value
    //   : list.findIndex((e) => e[tabData.type] == tabData[tabData.type]);

    const index = list.findIndex(
      (e) => e[tabData.type] == tabData[tabData.type]
    );

    // console.log("-----appendTab:index", index);

    if (index == -1) {
      // 该判断解决 type == 'path' 且 开启缓存页面情况下，标签标题会更新为路由默认title的问题。
      //   if (!(target && target.keepAlive && tabData.keepAlive)) {
      list.push(tabData);
      //   }
    } else {
      // console.log("tabData", tabData, isNumber(targetIndex.value));

      // if (!isNumber(targetIndex.value)) {
      // console.log("list[index] = tabData;", list[index], tabData);

      list[index] = tabData;
      // }
    }
  };

  // 移除Tab
  const closeTab = (param: number | TMenu) => {
    // 即将移除Tab的索引
    let index = isNumber(param) ? param : -1;

    const { value: list } = tabsList;

    if (!isNumber(param)) {
      // 如果不是索引，需要查找索引
      const { type } = param;
      const targetValue = param[type];
      index = list.findIndex((e) => e[type] == targetValue);
    }

    if (index > -1) {
      // 最大索引值
      const maxLength = list.length - 1;
      const isActive = acticeIndex.value == index;

      list.splice(index, 1);

      if (isActive) {
        // 关闭当前激活项时，需要切换到其他路由
        const nextTab = index == maxLength ? list.at(-1) : list[index];
        nextTab && router.push(nextTab.fullPath);
      }
    }
  };

  /**
   * 清除初激活状态的所有Tab
   */
  const clearTabsExceptActive = () => {};

  // 移除所有标签
  const clearAllTabs = () => {
    tabsList.value.length = 0;
    targetIndex.value = undefined;

    router.push("/");
  };

  // 完全清除历史记录
  const clear = () => (tabsList.value.length = 0);

  // 净化标签页列表，移除没有标题的标签页(偶现tab没有title的情况)
  const sanitizeTabList = () => {
    tabsList.value = tabsList.value.filter((e) => e.title);
  };

  sanitizeTabList();

  return {
    tabsList,
    acticeIndex,
    aliveIncludes,

    clear,
    appendTab,
    changeTab,

    closeTab,
    clearAllTabs,
  };
});

export const setAppTabsId = (id: string | number) => (appNavTabsId = id);

export default useAppTabsStore;
